package com.wy.demo.init;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

@Component
@Slf4j
public class ScreenshotServiceInit implements ApplicationRunner {
    @Value("${screenshot.server.url}")
    private String screenshotServerUrl;
    @Value("${screenshot.server.node-service-path}")
    private String node_service_path;
    @Value("${screenshot.server.port}")
    private String port;
    private Process nodeProcess;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("开始启动截图HTTP服务...");
        startNodeService();
        waitForServiceReady();
        log.info("截图HTTP服务启动完成");
    }

    /**
     * 启动Node.js服务
     */
    private void startNodeService() throws IOException {
        File serviceFile = new File(node_service_path);

        if (!serviceFile.exists()) {
            throw new RuntimeException("Node.js服务脚本不存在: " + node_service_path);
        }

        log.info("Node.js服务脚本路径: {}", serviceFile.getAbsolutePath());

        // 启动Node.js进程
        ProcessBuilder processBuilder = new ProcessBuilder("node", serviceFile.getName());
        processBuilder.directory(serviceFile.getParentFile());
        processBuilder.environment().put("PORT", port);

        // 重定向输出到日志
        processBuilder.redirectErrorStream(true);

        nodeProcess = processBuilder.start();

        // 启动线程读取Node.js进程输出
        Thread outputThread = new Thread(() -> {
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(nodeProcess.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    log.info("[Node.js] {}", line);
                }
            } catch (IOException e) {
                log.error("读取Node.js进程输出时出错", e);
            }
        });
        outputThread.setDaemon(true);
        outputThread.start();
    }

    /**
     * 等待服务就绪
     */
    private void waitForServiceReady() {
        int maxRetries = 30; // 最多等待30秒
        int retryCount = 0;

        while (retryCount < maxRetries) {
            try {
                URL url = new URL(screenshotServerUrl + "/health");
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(1000);
                connection.setReadTimeout(1000);

                int responseCode = connection.getResponseCode();
                if (responseCode == 200) {
                    log.info("截图HTTP服务已就绪");
                    return;
                }

                connection.disconnect();
            } catch (Exception e) {
                // 忽略连接异常，继续重试
            }

            retryCount++;
            try {
                Thread.sleep(1000); // 等待1秒后重试
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("等待服务就绪时被中断", e);
            }
        }

        throw new RuntimeException("截图HTTP服务启动超时");
    }

    /**
     * 应用关闭时清理资源
     */
    @PreDestroy
    public void cleanup() {
        log.info("开始清理截图服务资源...");

        // 尝试优雅关闭Node.js服务
        try {
            URL url = new URL(screenshotServerUrl + "/shutdown");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setConnectTimeout(2000);
            connection.setReadTimeout(2000);
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "application/json");

            int responseCode = connection.getResponseCode();
            log.info("发送关闭请求，响应码: {}", responseCode);
            connection.disconnect();

            // 等待进程自然结束
            if (nodeProcess != null && nodeProcess.isAlive()) {
                boolean finished = nodeProcess.waitFor(5, java.util.concurrent.TimeUnit.SECONDS);
                if (!finished) {
                    log.warn("Node.js进程未在5秒内结束，强制终止");
                    nodeProcess.destroyForcibly();
                }
            }

        } catch (Exception e) {
            log.error("优雅关闭Node.js服务失败，尝试强制终止", e);
            if (nodeProcess != null && nodeProcess.isAlive()) {
                nodeProcess.destroyForcibly();
            }
        }

        log.info("截图服务资源清理完成");
    }
}
